#!/bin/bash

:<<EOF
系统配置工具源码
Version: 1.1 for all
Update: 2022-09-18
Author: ahat_hua

这是一个可用的实用工具
也是一个可学习的代码
里面涵盖了shell编程的60%+基础知识点
EOF

# 进度条
# TODO 有bug, 没用进度条
progress() {
    while :
    do
        echo -n "#"
        sleep 0.2
    done
}

# 工具菜单
menu() {
    echo -e "\033[33m=========================================================================="
    printf "%-10s %-60s\n" "*" "欢迎使用系统配置工具 v1.1"
    printf "*\n"
    printf "%-4s %-20s %-20s %-30s\n" "*" "(a)_vim配置" "(b)_nvim配置" "(q)_退出此工具"
    echo -e "==========================================================================\033[0m"
    echo $1
}

# 配置的每部分内容
# 文件描述部分，合并到了vim02
# 版本号和作者部分
vim02_ver=$(cat <<- EOF
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Description: nvim/init.vim config file for Win
" Version: v0.1.9
" Create: 2022.09.18
" Email: yhua.lin@qq.com
" Author: ahat_hua
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

EOF
)
# 基本配置部分
vim03_basic=$(cat <<- EOF
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 基本配置
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"文件类型
filetype on

"状态栏
"set showmode
"set ruler
set showcmd

"制表符
"set smarttab    "根据原文缩进确定缩进
"插入模式下输入【ctrl+v+i】可以强制输入一个tab
set tabstop=4     "tabstop 表示一个 tab 显示出来是多少个空格的长度，默认8
set softtabstop=4 "softtabstop 表示在编辑模式的时候按退格键的时候退回缩进的长度，当使用 expandtab 时特别有用
set expandtab     "当设置成 expandtab 时，缩进用空格来表示，noexpandtab 则是用制表符表示一个缩进
set autoindent    "自动缩进
set cindent       "自动缩进补充
set shiftwidth=4  "自动缩进空白字符个数

"未保时存可以切换缓冲区
set hidden

"控制台响铃
set noerrorbells
set novisualbell

"行号和相对行号
set nu
set relativenumber

"当前光标状态
"set cursorcolumn
set cursorline
"set cursorlineopt=both

EOF
)
# 键位映射部分
vim04_map=$(cat <<- EOF
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Esc 映射键位
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
map <F4> <Esc>
map <Tab> <Esc>
vmap <Tab> <Esc>
imap <F4> <Esc>
imap <C><C> <Esc>

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 键位映射列表
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"修改文件后遭遇无权限写入的保存办法
cmap ,w!! w !sudo tee > /dev/null %

EOF
)
# 插件管理部分
vim05_plug=$(cat <<- EOF
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 插件管理列表
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"vim-plug插件管理器，插件放这块里
call plug#begin('E:\vim\nvimplug\plugged')
"Plug 'xxx/xxx'

"底部状态栏增强
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
"主题
"Plug 'nlknguyen/papercolor-theme'
"Plug 'morhetz/gruvbox'
Plug 'joshdick/onedark.vim'
Plug 'tomasr/molokai'
"Plug 'tomasr/molokai2me'
"修改围绕的引号、括号、HTML标签等
Plug 'tpope/vim-surround'
"快速移动
Plug 'easymotion/vim-easymotion'
"彩虹括号
Plug 'luochen1990/rainbow'
"驼峰命名单词的跳转和操作
"Plug 'bkad/camelcasemotion'
"更高级的围绕操作
"Plug 'wellle/targets.vim'
"多光标编辑
"Plug 'terryma/vim-multiple-cursors'
"HTML快速生成
"Plug 'mattn/emmet-vim'
"显示缩进线
"Plug 'yggdroot/indentline'
"超快内容搜索
"Plug 'rking/ag.vim'
"很适合代码分析用
"Plug 'majutsushi/tagbar'
"全路径模糊查找文件打开
"Plug 'kien/ctrlp.vim'
"文件目录树
"Plug 'scrooloose/nerdtree'
"在目录树中的Git状态
"Plug 'xuyuanp/nerdtree-git-plugin'
"注释代码
"Plug 'scrooloose/nerdcommenter'
"侧边栏提示Git修改状态
"Plug 'airblade/vim-gitgutter'
"迷你代码地图
"Plug 'severin-lemaignan/vim-minimap'
"CSS颜色预览
"Plug 'ap/vim-css-color'
"Nginx配置文件语法高亮
"Plug 'chr4/nginx.vim'
"Dockerfile
"Plug 'ekalinin/dockerfile.vim'

call plug#end()

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 主题配色插件配置
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
set t_Co=256
"插件配置，要安装了插件，才开启，不然报错
"PaperColor设置项
"set background=light
set background=dark
"colorscheme PaperColor

"colorscheme onedark
"colorscheme gruvbox

let g:molokai_original = 1
"let g:rehash256 = 1
colorscheme molokai

"let g:molokai2me_original = 1
"let g:rehash256me = 1
"colorscheme molokai2me

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 插件配置
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"加强状态栏的颜色配置
let g:airline_theme='onedark'

"彩虹括号配置项
let g:rainbow_active = 1 "0 if you want to enable it later via :RainbowToggle

EOF
)

# 构建vim配置
build_vim_config() {
    # $1系统，$2是否有插件，$3插件安装路径
    echo '开始构建vim配置'
    # TODO 测试用路径，完成测试后，改成真实路径
    plug_path=$HOME"/.vim/autoload"
    plug_vim_name="plug.vim"
    # TODO 测试用文件，完成测试后，改成真实文件
    vimrc_name=".vimrc"
    # plug.vim and .vimrc file
    plug_vim_file="${plug_path}/${plug_vim_name}"
    vimrc_file="${HOME}/${vimrc_name}"

    # 插件管理器部分
    if [ -e $plug_vim_file ]; then
        # 备份存在的文件
        cp $plug_vim_file "${HOME}/${plug_vim_name}_sh_bak"
    else
        # 不存插件管理器文件
        # 创建插件管理器目录
        # 下载插件管理器文件
        #mkdir -p ${plug_path}
        # 采用curl，下载并创建指定目录保存
        curl -Lo ${plug_vim_file} --create-dirs https://raw.iqiq.io/junegunn/vim-plug/master/plug.vim
    fi

    # 创建配置临时文件
    # 组装最终的配置文件
    tmp_file="${PWD}/${vimrc_name}_tmp"
    touch $tmp_file
    # 分片的配置文件
    # 以后更改的配置都写到这些分片文件
    #vim01_desc_file="${PWD}/vim/vim01_desc"
    vim02_ver_file="${PWD}/vim/vim02_ver"
    vim03_basic_file="${PWD}/vim/vim03_basic"
    vim04_map_file="${PWD}/vim/vim04_map"
    vim05_plug_file="${PWD}/vim/vim05_plug"
    # 以分片配置文件为主，没有分片配置文件，才用内置默认的配置
    # file01 第一个部分，采用覆盖写入
#     if [[ -e $vim01_desc_file && -s $vim01_desc_file ]]; then
#         cat $vim01_desc_file > $tmp_file
#     else
#         cat > $tmp_file <<- EOF
# ${vim01_desc}
# EOF
#     fi
    # file02 第二部分后的，都采用追加写入
    # file01 合并到 file02
    if [[ -e $vim02_ver_file && -s $vim02_ver_file ]]; then
        cat $vim02_ver_file > $tmp_file
    else
        cat > $tmp_file <<- EOF
${vim02_ver}
EOF
    fi
    # 分片配置文件最后空行无效，可能要追加一个空行
    echo '' >> $tmp_file
    # file03
    if [[ -e $vim03_basic_file && -s $vim03_basic_file ]]; then
        cat $vim03_basic_file >> $tmp_file
    else
        cat >> $tmp_file <<- EOF
${vim03_basic}
EOF
    fi
    echo '' >> $tmp_file
    # file04
    if [[ -e $vim04_map_file && -s $vim04_map_file ]]; then
        cat $vim04_map_file >> $tmp_file
    else
        cat >> $tmp_file <<- EOF
${vim04_map}
EOF
    fi
    echo '' >> $tmp_file
    # file05
    if [[ -e $vim05_plug_file && -s $vim05_plug_file ]]; then
        cat $vim05_plug_file >> $tmp_file
    else
        cat >> $tmp_file <<- EOF
${vim05_plug}
EOF
    fi
    echo '' >> $tmp_file

    # 备用的一些正则表达式参考
    #sed -r -n '/^".+in$/c\" Description: nvim/init.vim config file for Win' .vimrc_test_tmp
    #sed -r -n "/^\".+in$/c\" Description: .vimrc config file for Win" .vimrc_test_tmp
    #sed -r -n '/^call.*#begin/c\"call plug#begin()' .vimrc_test_tmp
    #sed -r -n "/^call.*#begin/c\"call plug#begin()" .vimrc_test_tmp
    #sed -r -n '/^call.*#end/c\"call plug#end()' .vimrc_test_tmp
    #sed -r -n "/^call.*#end/c\"call plug#end()" .vimrc_test_tmp
    #sed -r -n 's/^Plug /"&/'p .vimrc_test_tmp
    #sed -r -n "s/^Plug '.*/\"&/p" .vimrc_test_tmp
    #sed -r -n 's/^colorscheme /"&/'p .vimrc_test_tmp
    #sed -r -n "s/^colorscheme /\"&/p" .vimrc_test_tmp
    #sed -r -n 's/^let g.*/"&/'p .vimrc_test_tmp
    #sed -r -n "s/^let g.*/\"&/p" .vimrc_test_tmp

    # 按不同系统需求替换临时配置文件内容
    if [ $1 = '1' ]; then
        sed -r -i "/^\".+in$/c\" Description: ~/.vimrc config file for Linux" $tmp_file
    elif [ $1 = '2' ]; then
        sed -r -i "/^\".+in$/c\" Description: ~/.vimrc config file for Win" $tmp_file
    fi
    if [ -z $3 ]; then
        plug_begin="call plug#begin()"
    else
        plug_begin="call plug#begin('"$3"')"
    fi
    if [ $2 = 1 ]; then
        sed -r -i "/^call.*#begin/c${plug_begin}" $tmp_file
        sed -r -i "/^call.*#end/c\call plug#end()" $tmp_file
    elif [ $2 = 0 ]; then
        sed -r -i "/^call.*#begin/c\"${plug_begin}" $tmp_file
        sed -r -i "/^call.*#end/c\"call plug#end()" $tmp_file
        sed -r -i "s/^Plug '.*/\"&/" $tmp_file
    fi
    # 默认插件的配置都注释掉，安装完才手动开启
    # 插件未安装，开启插件配置，可能会造成报错
    sed -r -i "s/^colorscheme /\"&/" $tmp_file
    sed -r -i "s/^let g.*/\"&/" $tmp_file

    # 配置文件处理
    # 最终目的
    if [ -e $vimrc_file ]; then
        cp $vimrc_file "${HOME}/${vimrc_name}_sh_bak"
        while :
        do
            echo -e "\033[33m=====构造vim配置======\033[0m"
            read -p "是否替换现有配置？[ y/n ][ 默认替换操作 ] " update
            if [ -z $update ]; then
                update='y'
            fi
            if [ $update = 'y' ]; then
                cat $tmp_file > $vimrc_file
                rm $tmp_file
                echo -e "\033[32m构建更新配置完成\033[0m"
                break
            elif [ $update = 'n' ]; then
                rm $tmp_file
                echo -e "\033[31m你已取消操作\033[0m"
                break
            else
                continue
            fi
        done
    else
        cat $tmp_file > $vimrc_file
        rm $tmp_file
        echo -e "\033[32m配置文件构造完成\033[0m"
    fi
    exit 0
}

# vim配置
do_vim() {
    while :
    do
        echo -e "\033[33m=====vim配置-选择系统======\033[0m"
        echo -e "\033[37m 1) Linux (默认) \033[0m"
        echo -e "\033[33m 2) Win10+         \033[0m"
        echo -e "\033[33m 9) 返回上级菜单 \033[0m"
        echo -e "\033[33m 0) 退出配置       \033[0m"
        read -p "请选择系统：[ 默认Linux ] " sys
        # 字符长度为零，没输入东西
        # 太懒了，给它设置一个默认值吧
        if [ -z $sys ]; then
            sys='1'
        fi
        if [ $sys = '1' ]; then
            # Linux '1'
            while :
            do
                echo -e "\033[33m=====vim配置 for Linux - 选择功能======\033[0m"
                read -p "是否带插件？[ y/n ][ 默认无插件 ] " yes
                if [ -z $yes ]; then
                    yes='n'
                fi
                if [ $yes = 'y' ]; then
                    yes=1
                    #build_vim_config ${sys} ${yes}
                    break
                elif [ $yes = 'n' ]; then
                    yes=0
                    #build_vim_config ${sys} ${yes}
                    break
                else
                    continue
                fi
            done
            plugged=''
            # 按照需求构建配置
            build_vim_config ${sys} ${yes} ${plugged}
        elif [ $sys = '2' ]; then
            # Win10+ '2'
            while :
            do
                echo -e "\033[33m=====vim配置 for Win10 - 选择功能======\033[0m"
                read -p "是否带插件？[ y/n ][ 默认无插件 ] " yes
                if [ -z $yes ]; then
                    yes='n'
                fi
                if [ $yes = 'y' ]; then
                    yes=1
                    #build_vim_config ${sys} ${yes}
                    break
                elif [ $yes = 'n' ]; then
                    yes=0
                    #build_vim_config ${sys} ${yes}
                    break
                else
                    continue
                fi
            done
            # 获取插件下载存放路径
            # 这是Win的配置，不用默认路径，让C盘不会塞爆
            # 最好先建好目录，用脚本创建，可能有权限问题
            while :
            do
                echo -e "\033[33m=====vim配置 for Win10 - 选择功能======\033[0m"
                read -p "配置指定插件下载存放路径[ 例如：/e/vim/vimplug/plugged ][ 使用默认路径 ] " plugged
                if [ -z $plugged ]; then
                    plugged=''
                    break
                else
                    mkdir -p $plugged
                    break
                fi
            done
            # 按照需求构建配置
            build_vim_config ${sys} ${yes} ${plugged}
        elif [ $sys = '9' ]; then
            break
        elif [ $sys = '0' ]; then
            exit 0
        else
            echo '选择错误！'
        fi
    done
}

# 构建nvim配置
build_nvim_config() {
    # $1系统，$2是否有插件，$3插件安装路径
    echo '开始构建nvim配置'
    plug_vim_name="plug.vim"
    # TODO 测试用文件，完成测试后，改成真实文件
    nvim_name="init.vim"
    # 这个nvim配置，Win和Linux默认路径相差太大了
    # TODO 测试用路径，完成测试后，改成真实路径
    if [ $1 = '1' ]; then
        plug_path=$HOME"/.local/share/nvim/site/autoload"
        nvim_path="${HOME}/.config/nvim"
        nvim_file="${nvim_path}/${nvim_name}"
    elif [ $1 = '2' ]; then
        nvim_path="${HOME}/AppData/Local/nvim"
        plug_path=$nvim_path"/autoload"
        nvim_file="${nvim_path}/${nvim_name}"
    fi
    plug_vim_file="${plug_path}/${plug_vim_name}"

    # 插件管理器部分
    if [ -e $plug_vim_file ]; then
        cp $plug_vim_file "${HOME}/${plug_vim_name}_sh_bak"
    else
        # 不存插件管理器文件
        # 创建插件管理器目录
        # 下载插件管理器文件
        #mkdir -p ${plug_path}
        # curl可以自动创建目录，用wget可能要mkdir -p创建目录
        curl -Lo ${plug_vim_file} --create-dirs https://raw.iqiq.io/junegunn/vim-plug/master/plug.vim
        # 由于GitHub无法访问，这个链接是镜像加速的网址，如果失效了，要重新找一个
    fi

    # 创建配置临时文件
    # 组装最终的配置文件
    tmp_file="${PWD}/${nvim_name}_tmp"
    touch $tmp_file
    # 跟vim共用配置
    #vim01_desc_file="${PWD}/vim/vim01_desc"
    vim02_ver_file="${PWD}/vim/vim02_ver"
    vim03_basic_file="${PWD}/vim/vim03_basic"
    vim04_map_file="${PWD}/vim/vim04_map"
    vim05_plug_file="${PWD}/vim/vim05_plug"
    # file01
#     if [[ -e $vim01_desc_file && -s $vim01_desc_file ]]; then
#         cat $vim01_desc_file > $tmp_file
#     else
#         cat > $tmp_file <<- EOF
# ${vim01_desc}
# EOF
#     fi
    # file02 已合并 file01 内容
    if [[ -e $vim02_ver_file && -s $vim02_ver_file ]]; then
        cat $vim02_ver_file > $tmp_file
    else
        cat > $tmp_file <<- EOF
${vim02_ver}
EOF
    fi
    echo '' >> $tmp_file
    # file03
    if [[ -e $vim03_basic_file && -s $vim03_basic_file ]]; then
        cat $vim03_basic_file >> $tmp_file
    else
        cat >> $tmp_file <<- EOF
${vim03_basic}
EOF
    fi
    echo '' >> $tmp_file
    # file04
    if [[ -e $vim04_map_file && -s $vim04_map_file ]]; then
        cat $vim04_map_file >> $tmp_file
    else
        cat >> $tmp_file <<- EOF
${vim04_map}
EOF
    fi
    echo '' >> $tmp_file
    # file05
    if [[ -e $vim05_plug_file && -s $vim05_plug_file ]]; then
        cat $vim05_plug_file >> $tmp_file
    else
        cat >> $tmp_file <<- EOF
${vim05_plug}
EOF
    fi
    echo '' >> $tmp_file

    #sed -r -n '/^".+in$/c\" Description: nvim/init.vim config file for Win' .vimrc_test_tmp
    #sed -r -n "/^\".+in$/c\" Description: .vimrc config file for Win" .vimrc_test_tmp
    #sed -r -n '/^call.*#begin/c\"call plug#begin()' .vimrc_test_tmp
    #sed -r -n "/^call.*#begin/c\"call plug#begin()" .vimrc_test_tmp
    #sed -r -n '/^call.*#end/c\"call plug#end()' .vimrc_test_tmp
    #sed -r -n "/^call.*#end/c\"call plug#end()" .vimrc_test_tmp
    #sed -r -n 's/^Plug /"&/'p .vimrc_test_tmp
    #sed -r -n "s/^Plug '.*/\"&/p" .vimrc_test_tmp
    #sed -r -n 's/^colorscheme /"&/'p .vimrc_test_tmp
    #sed -r -n "s/^colorscheme /\"&/p" .vimrc_test_tmp
    #sed -r -n 's/^let g.*/"&/'p .vimrc_test_tmp
    #sed -r -n "s/^let g.*/\"&/p" .vimrc_test_tmp

    # 按不同系统需求替换临时配置文件内容
    if [ $1 = '1' ]; then
        sed -r -i "/^\".+in$/c\" Description: nvim/init.vim config file for Linux" $tmp_file
    elif [ $1 = '2' ]; then
        sed -r -i "/^\".+in$/c\" Description: nvim/init.vim config file for Win" $tmp_file
    fi
    if [ -z $3 ]; then
        plug_begin="call plug#begin()"
    else
        plug_begin="call plug#begin('"$3"')"
    fi
    if [ $2 = 1 ]; then
        sed -r -i "/^call.*#begin/c${plug_begin}" $tmp_file
        sed -r -i "/^call.*#end/c\call plug#end()" $tmp_file
    elif [ $2 = 0 ]; then
        sed -r -i "/^call.*#begin/c\"${plug_begin}" $tmp_file
        sed -r -i "/^call.*#end/c\"call plug#end()" $tmp_file
        sed -r -i "s/^Plug '.*/\"&/" $tmp_file
    fi
    sed -r -i "s/^colorscheme /\"&/" $tmp_file
    sed -r -i "s/^let g.*/\"&/" $tmp_file

    # 配置文件处理
    # 最终目的
    if [ -e $nvim_file ]; then
        cp $nvim_file "${HOME}/${nvim_name}_sh_bak"
        while :
        do
            echo -e "\033[33m=====构造nvim配置======\033[0m"
            read -p "是否替换现有配置？[ y/n ][ 默认替换操作 ] " update
            if [ -z $update ]; then
                update='y'
            fi
            if [ $update = 'y' ]; then
                cat $tmp_file > $nvim_file
                rm $tmp_file
                echo -e "\033[32m构建更新配置完成\033[0m"
                break
            elif [ $update = 'n' ]; then
                rm $tmp_file
                echo -e "\033[31m你已取消操作\033[0m"
                break
            else
                continue
            fi
        done
    else
        # 创建不同系统的配置目录
        if [ $1 = '1' ]; then
            mkdir -p nvim_path
        elif [ $1 = '2' ]; then
            mkdir -p nvim_path
        fi
        cat $tmp_file > $nvim_file
        rm $tmp_file
        echo -e "\033[32m配置文件构造完成\033[0m"
    fi
    exit 0
}

# nvim配置
do_nvim() {
    while :
    do
        echo -e "\033[33m=====nvim配置-选择系统======\033[0m"
        echo -e "\033[37m 1) Linux (默认) \033[0m"
        echo -e "\033[33m 2) Win10+         \033[0m"
        echo -e "\033[33m 9) 返回上级菜单 \033[0m"
        echo -e "\033[33m 0) 退出配置       \033[0m"
        read -p "请选择系统：[ 默认Linux ] " sys
        # 字符长度为零，没输入东西
        # 太懒了，给它设置一个默认值吧
        if [ -z $sys ]; then
            sys='1'
        fi
        if [ $sys = '1' ]; then
            # Linux
            while :
            do
                echo -e "\033[33m=====nvim配置 for Linux - 选择功能======\033[0m"
                read -p "是否带插件？[ y/n ][ 默认无插件 ] " yes
                if [ -z $yes ]; then
                    yes='n'
                fi
                if [ $yes = 'y' ]; then
                    yes=1
                    break
                elif [ $yes = 'n' ]; then
                    yes=0
                    break
                else
                    continue
                fi
            done
            plugged=''
            # 按照需求构建配置
            build_nvim_config ${sys} ${yes} ${plugged}
        elif [ $sys = '2' ]; then
            # Win10+
            while :
            do
                echo -e "\033[33m=====nvim配置 for Win10 - 选择功能======\033[0m"
                read -p "是否带插件？[ y/n ][ 默认无插件 ] " yes
                if [ -z $yes ]; then
                    yes='n'
                fi
                if [ $yes = 'y' ]; then
                    yes=1
                    break
                elif [ $yes = 'n' ]; then
                    yes=0
                    break
                else
                    continue
                fi
            done
            # 获取插件下载存放路径
            while :
            do
                echo -e "\033[33m=====nvim配置 for Win10 - 选择功能======\033[0m"
                read -p "配置指定插件下载存放路径[ 例如：E:\vim\nvimplug\plugged ][ 使用默认路径 ] " plugged
                if [ -z $plugged ]; then
                    plugged=''
                    break
                else
                    mkdir -p $plugged
                    break
                fi
            done
            # 按照需求构建配置
            build_nvim_config ${sys} ${yes} ${plugged}
        elif [ $sys = '9' ]; then
            break
        elif [ $sys = '0' ]; then
            exit 0
        else
            echo '选择错误！'
        fi
    done
}

# 脚本主函数
main() {
    msg=''
    while :
    do
        menu $msg
        read -p "选择菜单，请输入菜单字母：[ 默认vim ] " opt
        if [ -z $opt ]; then
            opt='a'
        fi
        case ${opt} in
            a) do_vim
            ;;
            b) do_nvim
            ;;
            q) break
            ;;
            *) msg="你的选择有误！"
            ;;
        esac
    done
    exit 0
}

# 运行
main
